#ifndef __CXHGT_CHEST_FORTIFY_H__
#define __CXHGT_CHEST_FORTIFY_H__

#include <map>
#include <mutex>
#include "nlohmann/json.hpp"

#include "Engine/Point3.hpp"
#include "Engine/GameGuid.h"

#include "Expand/IPlugin.h"

using namespace PocketSurvival;
using namespace PocketSurvival::Engine;

namespace PocketSurvival
{
    class AuthPlugin;
};

namespace CXHGT
{
    struct ChestFortifyData
    {
        GameGuid userGuid;
        uint32_t fortifyCount;      // 强化剩余次数

        friend inline void to_json(nlohmann::json &json, const ChestFortifyData &chestFortifyData)
        {
            json = {
                {"UserGuid", chestFortifyData.userGuid},
                {"FortifyCount", chestFortifyData.fortifyCount}
            };
        }
        friend inline void from_json(const nlohmann::json &json, ChestFortifyData &chestFortifyData)
        {
            chestFortifyData.userGuid = json["userGuid"].get<GameGuid>();
            chestFortifyData.fortifyCount = json["FortifyCount"].get<uint32_t>();
        }
    };

    class PlayerEvent;

    class ChestFortify : public IPlugin
    {
    public:
        int32_t lockBlockValue;           // 使用哪个方块可以上锁
        uint32_t addFortifyCount;       // 每次上锁增加的强度

    private:
        PlayerEvent *m_playerEvent;
        
        AuthPlugin *m_authPlugin;

        std::map<Point3, ChestFortifyData> m_chestFortifyMap;
        std::mutex m_mapMutex;

    public:
        ChestFortify();

        /**
         * @brief 是否为箱子的所有者
         * @return true：是所有者
         * @note 当箱子没有上锁时，也会返回 true
         */
        bool isOwner(const Point3& point, const GameGuid& userGuid);


        bool breakChest(const Point3& point, const GameGuid& userGuid);


        uint32_t addChestFortify(const Point3& point, const GameGuid& userGuid, uint32_t fortifyCount);

        virtual const std::string &getPluginName() override;
        virtual const std::string &getIntroduce() override;
        virtual uint32_t getUseAuthLevel() override;
        virtual AuthDisplayType getDisplayType() override;
        virtual void processCmd(ChatObj &chatObj, std::vector<std::string> &cmdDataVec) override;

        virtual void load() override;
        virtual void save() override;

        virtual void getCmds(std::vector<std::string> &cmdVec) override;
    };
}

#endif
